package microcredit.gui.base;

import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ComboBoxEditor;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

import org.jdesktop.swingx.autocomplete.AutoCompleteComboBoxEditor;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
import org.jdesktop.swingx.autocomplete.ObjectToStringConverter;

public abstract class EnumComboBox<E> extends JComboBox {

	private static final long serialVersionUID = 1L;

	private String nullValue;
	
	public EnumComboBox() {
		this.nullValue = null;
		setModel(new EnumComboBoxModel(new Object[]{}, nullValue));
		init();
	}
	
	public EnumComboBox(E[] values) {
		this.nullValue = null;
		setModel(new EnumComboBoxModel(filter(values), nullValue));
		init();
	}
	
	public EnumComboBox(E[] values, boolean addNullValue) {
		this.nullValue = convertToString(null);
		setModel(new EnumComboBoxModel(filter(values), nullValue));
		init();
	}
	
	@Override
	public void setModel(ComboBoxModel aModel) {
		super.setModel(aModel);
		if (aModel instanceof EnumComboBoxModel) {
			this.nullValue = (String)((EnumComboBoxModel) aModel).getNullValue();
		}
	}
	
	public void enableAutocompletion() {
		AutoCompleteDecorator.decorate(this, new ObjectToStringConverter() {
			@SuppressWarnings("unchecked")
			@Override
			public String getPreferredStringForItem(Object arg0) {
				if (arg0 != null && arg0.equals(nullValue))  {
					return (String)nullValue;
				}
				return convertToString((E)arg0);
			}
		});
	}
	
	
	@SuppressWarnings("unchecked")
	private E[] filter(E[] values) {
		List<E> filtered = new ArrayList<E>();
		if (values != null) {
			for (E e : values) {
				if (!isFiltered(e)) {
					filtered.add(e);
				}
			}
		}
		return (E[])filtered.toArray();
	}
	
	public abstract String convertToString(E enumValue);
	
	public boolean isFiltered(E enumValue) {
		return false;
	}
	
	@SuppressWarnings("unchecked")
	public E getValue() {
		Object value = getSelectedItem();
		if (value == nullValue) {
			return null;
		}
		return (E)value;
	}
	
	public void setValue(E value) {
		setSelectedItem(value == null ? nullValue : value);
		selectedItemChanged();
		revalidate();
		repaint();
	}
	
	private void init() {
		
		
		setRenderer(new DefaultListCellRenderer()  {
			private static final long serialVersionUID = 1L;

			@SuppressWarnings("unchecked")
			@Override
			public Component getListCellRendererComponent(JList list,
					Object value, int index, boolean isSelected,
					boolean cellHasFocus) {
				String stringValue;
				if (value == null || !value.equals(nullValue)) {
					stringValue = convertToString((E)value);
					if (stringValue != null) {
						if (stringValue.length() > 30) {
							stringValue = stringValue.substring(0, 30)+"...";
						}
					}
				} else {
					stringValue = nullValue;
				}

				JLabel label = (JLabel) super.getListCellRendererComponent(list, stringValue, index, isSelected,
						cellHasFocus);
				return label;
			}
			
		});
	}
	
	

}
